package com.big.common.core.util;

import cn.hutool.core.collection.CollUtil;

import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 条件处理工具类，提供链式条件判断和异常处理
 *
 * @author 山归岿
 * @create 2025-06-17-11:09
 */
public final class ConditionHandler {

    // ================ 条件分支处理器 ================ //
    public static void branch(boolean condition, Runnable trueAction) {
        if (condition) {
            trueAction.run();
        }
    }

    public static void branch(boolean condition, Runnable trueAction, Runnable falseAction) {
        if (condition) {
            trueAction.run();
        } else {
            falseAction.run();
        }
    }

    public static void branchOrThrow(boolean condition, Runnable trueAction, Supplier<RuntimeException> exceptionSupplier) {
        if (condition) {
            trueAction.run();
        } else {
            throw exceptionSupplier.get();
        }
    }

    public static void branchOrThrow(boolean condition, Supplier<RuntimeException> exceptionSupplier) {
        if (!condition) {
            throw exceptionSupplier.get();
        }
    }

    // ================ 非空处理器 ================ //
    public static <T> void ifPresent(T value, Consumer<? super T> action) {
        if (value != null) {
            action.accept(value);
        }
    }

    public static <T> void ifPresentOrElse(T value, Consumer<? super T> action, Runnable emptyAction) {
        if (value != null) {
            action.accept(value);
        } else {
            emptyAction.run();
        }
    }

    public static <T> void ifPresentOrThrow(T value, Consumer<? super T> action, Supplier<RuntimeException> exceptionSupplier) {
        if (value != null) {
            action.accept(value);
        } else {
            throw exceptionSupplier.get();
        }
    }

    // ================ 集合处理器 ================ //
    public static <T, C extends Collection<T>> void ifNotEmpty(C collection, Consumer<? super C> action) {
        if (CollUtil.isNotEmpty(collection)) {
            action.accept(collection);
        }
    }

    public static <T, C extends Collection<T>> void ifNotEmptyOrElse(C collection, Consumer<? super C> action, Runnable emptyAction) {
        if (CollUtil.isNotEmpty(collection)) {
            action.accept(collection);
        } else {
            emptyAction.run();
        }
    }

    public static <T, C extends Collection<T>> void ifNotEmptyOrThrow(C collection, Consumer<? super C> action, Supplier<RuntimeException> exceptionSupplier) {
        if (CollUtil.isNotEmpty(collection)) {
            action.accept(collection);
        } else {
            throw exceptionSupplier.get();
        }
    }

    // ================ 链式条件构建器 ================ //
    public static ConditionBuilder when(boolean condition) {
        return new ConditionBuilder(condition);
    }

    public static <T> ObjectBuilder<T> whenPresent(T value) {
        return new ObjectBuilder<>(value);
    }

    public static <T, C extends Collection<T>> CollectionBuilder<C> whenNotEmpty(C collection) {
        return new CollectionBuilder<>(collection);
    }

    // ================ 构建器类 ================ //
    public static final class ConditionBuilder {
        private final boolean condition;

        private ConditionBuilder(boolean condition) {
            this.condition = condition;
        }

        public void then(Runnable action) {
            if (condition) {
                action.run();
            }
        }

        public ConditionBuilder then(Runnable action, Runnable elseAction) {
            if (condition) {
                action.run();
            } else {
                elseAction.run();
            }
            return this;
        }

        public void orThrow(Supplier<RuntimeException> exceptionSupplier) {
            if (!condition) {
                throw exceptionSupplier.get();
            }
        }
    }

    public static final class ObjectBuilder<T> {
        private final T value;

        private ObjectBuilder(T value) {
            this.value = value;
        }

        public void then(Consumer<? super T> action) {
            if (value != null) {
                action.accept(value);
            }
        }

        public void orThrow(Supplier<RuntimeException> exceptionSupplier) {
            if (value == null) {
                throw exceptionSupplier.get();
            }
        }

        public void orElse(Runnable action) {
            if (value == null) {
                action.run();
            }
        }
    }

    public static final class CollectionBuilder<C extends Collection<?>> {
        private final C collection;

        private CollectionBuilder(C collection) {
            this.collection = collection;
        }

        public void then(Consumer<? super C> action) {
            if (CollUtil.isNotEmpty(collection)) {
                action.accept(collection);
            }
        }

        public void orThrow(Supplier<RuntimeException> exceptionSupplier) {
            if (CollUtil.isEmpty(collection)) {
                throw exceptionSupplier.get();
            }
        }

        public void orElse(Runnable action) {
            if (CollUtil.isEmpty(collection)) {
                action.run();
            }
        }
    }
}